package com.zhenzhang.myblog.aop;

import com.zhenzhang.myblog.annotations.Authentication;
import com.zhenzhang.myblog.entity.role.User;
import com.zhenzhang.myblog.entity.role.UserRole;
import com.zhenzhang.myblog.utils.JsonResult;
import com.zhenzhang.myblog.utils.validator.permission.ExcludeValidator;
import com.zhenzhang.myblog.utils.validator.permission.IncludeValidator;
import com.zhenzhang.myblog.utils.validator.permission.PermissionValidator;
import com.zhenzhang.myblog.utils.validator.permission.ValidMode;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Aspect
@Component
public class PermissionInterceptor {
    private final static PermissionValidator includeValidator = new IncludeValidator();
    private final static PermissionValidator excludeValidator = new ExcludeValidator();


    @Around("@annotation(com.zhenzhang.myblog.annotations.Authentication) && @annotation(ann)")
    public Object doAround(ProceedingJoinPoint pjp,Authentication ann) throws Throwable {
        PermissionValidator validator;
        if (ann.type() == ValidMode.INCLUDE) {
            validator = includeValidator;
        } else {
            validator = excludeValidator;
        }
        var attr = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes());
        var user = (User)attr
                .getRequest()
                .getSession()
                .getAttribute("loginUser");
        UserRole role;
        if (user == null) {
            role = UserRole.DEFAULT;
        } else if (user.getAdmin()) {
            role = UserRole.ADMIN;
        } else {
            role = UserRole.USER;
        }
        if (validator.valid(role, ann.role())) {
            return pjp.proceed();
        } else {
            attr.getResponse().setStatus(403);
            attr.getResponse().setContentType("application/json;charset=utf-8");
            attr.getResponse().getWriter().print(JsonResult.getInstance(403, "权限不足或登录失效"));
            return null;
        }
    }

}
